{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 用户定义的可调用类型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "\n",
    "class BingoCage:\n",
    "    def __init__(self, items):\n",
    "        self._items = list(items)\n",
    "        random.shuffle(self._items)\n",
    "        \n",
    "    def pick(self):\n",
    "        try:\n",
    "            return self._items.pop()\n",
    "        except IndexError:\n",
    "            raise LookupError('pick from empty BingoCage')\n",
    "            \n",
    "    def __call__(self):\n",
    "        return self.pick()\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bingo = BingoCage(range(3))\n",
    "bingo.pick()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bingo()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 从定位参数到仅限关键字参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def tag(name, *content, cls=None, **attrs):\n",
    "    \"\"\"生成一个或多个HTML标签\"\"\"\n",
    "    if cls is not None:\n",
    "        attrs['class'] = cls\n",
    "    if attrs:\n",
    "        attr_str = ''.join(' %s=\"%s\"' % (attr, value)\n",
    "                           for attr, value\n",
    "                           in sorted(attrs.items()))\n",
    "    else:\n",
    "        attr_str = ''\n",
    "    if content:\n",
    "        return '\\n'.join('<%s%s>%s</%s>' %\n",
    "                         (name, attr_str, c, name) for c in content)\n",
    "    else:\n",
    "        return '<%s%s />' % (name, attr_str)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'<div>hello</div>'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tag('div', 'hello')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
